package com.acme.bankapp.email;

import com.acme.bankapp.domain.Client;
import com.acme.bankapp.exception.EmailException;


/**
 * Created by Java Student on 11/21/2014.
 */
public class EmailService extends Thread{
    //TODO: Move thread to Queue
    private Queue queue = new Queue();
    volatile private boolean isClosedThread = false;
    final private Object queueMonitor = new Object();

    public EmailService() {
        start();
    }

    @Override
    public void run() {
        while(true){
            try {
                sendEmail();
            } catch (InterruptedException e) {
                System.out.println("Email service is closed");

                while (!queue.isEmpty()) {
                    try {
                        sendNotificationEmail(queue.getEmail());
                    } catch (InterruptedException ignored) {}
                }

                return;
            }
        }
    }

    public void sendEmail() throws InterruptedException {
        while (!queue.isEmpty()) {
            sendNotificationEmail(queue.getEmail());
        }

        synchronized (queueMonitor){
            while (queue.isEmpty()) {
                queueMonitor.wait();
            }
        }
    }

    public void addEmail(Client client, String address) throws EmailException {
        Email email = new Email(client, address);
        if(! isClosedThread){
            queue.add(email);
            synchronized (queueMonitor){
                queueMonitor.notify();
            }
        }
        else{
            throw new EmailException(email + " wasn't delivered!");
        }

    }

    public void close(){
        isClosedThread = true;
        interrupt();
    }

    public void sendNotificationEmail(Email email) throws InterruptedException {
        System.out.println(email + " is sended.");

        //Emulation of "long" work
        try {
            Thread.sleep((long) 1);
        } catch (InterruptedException e) {
            throw new InterruptedException();
        }
    }
}
